home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cocktail
/
cg.lha
/
cg
/
src
/
c4.puma
< prev
next >
Wrap
Text File
|
1992-11-24
|
19KB
|
675 lines
/* Ich, Doktor Josef Grosch, Informatiker, 18.12.1990 */
TRAFO EvalC2
TREE Tree
PUBLIC EvalImplC
GLOBAL {
FROM SYSTEM IMPORT ADR;
FROM IO IMPORT WriteS, WriteNl, WriteI, StdOutput;
FROM StringMem IMPORT WriteString;
FROM Idents IMPORT tIdent, WriteIdent;
FROM Texts IMPORT WriteText;
FROM Sets IMPORT tSet, MakeSet, ReleaseSet, Include, Minimum, IsElement, WriteSet;
FROM Relations IMPORT IsRelated;
FROM TreeC2 IMPORT WriteLine;
FROM EvalC IMPORT EvalImplHead;
FROM Tree IMPORT
NoTree , tTree , Referenced , NoCodeClass ,
Computed , Reverse , Write , Read ,
Inherited , Synthesized , Input , Output ,
Stack , Parameter , Variable ,
CopyDef , CopyUse , Thread , Virtual ,
Test , Left , Right , NonBaseComp ,
First , Dummy , Trace , ClassCount ,
Demand , Funct , NoClass , Options ,
TreeRoot , iModule , iMain , itTree ,
ForallClasses, ForallAttributes, f , WI , WN ,
IdentifyAttribute, GrammarClass, cOAG , MaxVisit ,
WriteInstance;
VAR
Start, Stop, Visit, ChildVisit, i, j, k : SHORTCARD;
Node, Attr, Class, AttrClass, Child, Child2, ChildsClass : tTree;
PROCEDURE Representative (i: CARDINAL): CARDINAL; (* Class *)
VAR
s : tSet;
r : CARDINAL;
Stable : BOOLEAN;
j, k : CARDINAL;
BEGIN
WITH Class^.Class DO
MakeSet (s, InstCount);
Include (s, i);
REPEAT
Stable := TRUE;
FOR j := 1 TO InstCount DO
IF IsElement (j, s) THEN
IF CopyDef IN Instance^[j].Properties THEN
k := Instance^[j].CopyArg;
IF (Parameter IN Instance^[k].Attribute^.Attribute.Properties) AND
NOT IsElement (k, s) THEN
Include (s, k);
Stable := FALSE;
END;
END;
IF CopyUse IN Instance^[j].Properties THEN
FOR k := 1 TO InstCount DO
IF (CopyDef IN Instance^[k].Properties) AND
(Parameter IN Instance^[k].Attribute^.Attribute.Properties) AND
(Instance^[k].CopyArg = j) AND
NOT IsElement (k, s) THEN
Include (s, k);
Stable := FALSE;
END;
END;
END;
END;
END;
UNTIL Stable;
r := Minimum (s);
IF r <= AttrCount THEN
Stable := TRUE;
j := r + 1;
LOOP
IF j > AttrCount THEN EXIT; END;
IF IsElement (j, s) THEN Stable := FALSE; EXIT; END;
INC (j);
END;
IF NOT Stable THEN
j := 1;
LOOP
k := Instance^ [j].Order;
IF (k <= AttrCount) AND IsElement (k, s) THEN r := k; EXIT; END;
INC (j);
END;
END;
END;
ReleaseSet (s);
RETURN r;
END;
END Representative;
PROCEDURE GenAttribute (i: CARDINAL; repr: BOOLEAN); (* Class = subtype, Node = current type, k *)
BEGIN
IF repr THEN
WITH Class^.Class.Instance^[i] DO
IF (Parameter IN Attribute^.Attribute.Properties) AND
(({CopyDef, CopyUse} * Properties) # {}) THEN
i := Representative (i);
END;
END;
END;
WITH Class^.Class.Instance^[i] DO
IF Virtual IN Properties THEN RETURN; END;
IF Left IN Properties THEN (* left *)
WITH Attribute^.Attribute DO
IF Parameter IN Properties THEN
IF IdentifyAttribute (Node, Name) = NoTree THEN
!yy! WI (Name); (* local *)
ELSE
!(* yy! WI (Name); !)! (* param *)
END;
ELSIF Demand IN Properties THEN (* demand *)
IF Funct IN Properties THEN
AttrClass := GetClass (Class, Name); (* function *)
!y! WI (AttrClass^.Class.Name); !y! WI (Name); ! (yyt)!
ELSIF i # k THEN
!yy! WI (Name); (* local *)
ELSE
!(* yy! WI (Name); !)! (* param *)
END;
ELSE (* tree *)
!yyt->! WI (Class^.Class.Name); !.! WI (Name);
END;
END;
ELSE (* right *)
WITH Attribute^.Attribute DO
IF Parameter IN Properties THEN
WI (Selector^.Child.Name); !yy! WI (Name); (* param *)
ELSIF Demand IN Properties THEN (* demand *)
IF Funct IN Properties THEN (* function *)
AttrClass := GetClass (Selector^.Child.Class, Name);
!y! WI (AttrClass^.Class.Name); !y! WI (Name);
! (yyt->! WI (Class^.Class.Name); !.! WI (Selector^.Child.Name); !)!
ELSE
WI (Selector^.Child.Name); !yy! WI (Name);
END;
ELSE (* tree *)
!yyt->! WI (Class^.Class.Name); !.! WI (Selector^.Child.Name);
!->! WI (Selector^.Child.Type); !.! WI (Name);
END;
END;
END;
END;
END GenAttribute;
PROCEDURE GetClass (Class: tTree; Attribute: tIdent): tTree;
BEGIN
WHILE Class^.Kind # NoClass DO
IF IdentifyAttribute (Class^.Class.Attributes, Attribute) # NoTree THEN RETURN Class; END;
Class := Class^.Class.BaseClass;
END;
RETURN NoTree;
END GetClass;
PROCEDURE CheckUsage (Usage: BITSET): BOOLEAN; (* Class, Child, Start, Stop *)
VAR i, i2: SHORTCARD;
BEGIN
FOR i := Start TO Stop DO
i2 := Class^.Class.Instance^ [i].Order;
WITH Class^.Class.Instance^ [i2] DO
IF ({Synthesized, Right, First} <= Properties) AND
(Child = Selector) AND
(Attribute^.Child.Partition <= Selector^.Child.Class^.Class.Visits) AND
(Attribute^.Child.Partition IN Usage) THEN
RETURN TRUE;
END;
IF ({Inherited, Right} <= Properties) AND (i2 = j) THEN
RETURN TRUE;
END;
END;
END;
RETURN FALSE;
END CheckUsage;
}
BEGIN { k := 0; }
PROCEDURE EvalImplC (t: Tree)
Ag (..) :- {
EvalImplHead (t);
!!
ForallClasses (Classes, Forward);
!!
!void ! WI (EvalName); !!
!# if defined __STDC__ | defined __cplusplus!
! (! WI (itTree); ! yyt)!
!# else!
! (yyt) ! WI (itTree); ! yyt;!
!# endif!
Node := Classes;
Class := Classes;
!{!
ForallAttributes (Class, GenTemposLocal);
IF NOT IsElement (ORD ('9'), Options) THEN
IF MaxVisit > 0 THEN
Class := Classes;
Visit := 1;
! yyVisit1! WI (Class^.Class.Name); ! (yyt!
ForallAttributes (Class, GenActualsLeft);
!);!
END;
! }!
ELSE
! char xxHigh;!
! xxStack = 1000000000;!
IF MaxVisit > 0 THEN
Class := Classes;
Visit := 1;
! yyVisit1! WI (Class^.Class.Name); ! (yyt!
ForallAttributes (Class, GenActualsLeft);
!);!
END;
@ (void) printf ("Stacksize %d\n", (int) & xxHigh - xxStack);@
!}!
END;
!!
ForallClasses (Classes, GenDemandProc);
ForallClasses (Classes, EvalImplC);
!void Begin! WI (EvalName); ! ()!
!{!
WriteLine (EvalCodes^.Codes.BeginLine);
WriteText (f, EvalCodes^.Codes.Begin);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteLine (Node^.Module.EvalCodes^.Codes.BeginLine);
WriteText (f, Node^.Module.EvalCodes^.Codes.Begin);
Node := Node^.Module.Next;
END;
!}!
!!
!void Close! WI (EvalName); ! ()!
!{!
WriteLine (EvalCodes^.Codes.CloseLine);
WriteText (f, EvalCodes^.Codes.Close);
Node := Modules;
WHILE Node^.Kind = Tree.Module DO
WriteLine (Node^.Module.EvalCodes^.Codes.CloseLine);
WriteText (f, Node^.Module.EvalCodes^.Codes.Close);
Node := Node^.Module.Next;
END;
!}!
}; .
Class (..) :- {
IF (NoCodeClass * Properties) # {} THEN RETURN; END;
IF Referenced IN Properties THEN
Generated := 0;
ForallClasses (Extensions, Generated0);
FOR Visit := 1 TO Visits DO
Node := t;
Class := t;
!static void yyVisit! WN (Visit); WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
! (register ! WI (itTree); ! yyt! ForallAttributes (t, GenFormals3); !)!
!# else!
! (yyt! ForallAttributes (t, GenFormals1); !)!
! register ! WI (itTree); ! yyt;!
ForallAttributes (t, GenFormals2);
!# endif!
!{!
WriteLine (TreeRoot^.Ag.EvalCodes^.Codes.LocalLine);
WriteText (f, TreeRoot^.Ag.EvalCodes^.Codes.Local);
Node := TreeRoot^.Ag.Modules;
WHILE Node^.Kind = Tree.Module DO
WriteLine (Node^.Module.EvalCodes^.Codes.LocalLine);
WriteText (f, Node^.Module.EvalCodes^.Codes.Local);
Node := Node^.Module.Next;
END;
IF IsElement (ORD ('9'), Options) THEN
! char xxLow;!
! xxStack = Min (xxStack, (int) & xxLow);!
END;
! switch (yyt->Kind) {!
IF cOAG IN GrammarClass THEN (* generate evaluator *)
Node := t;
GenEvaluator (t);
ForallClasses (Extensions, GenEvaluator);
END;
! default: ;!
IF IsElement (ORD ('Z'), Options) THEN
! yyVisitParent (yyt);!
END;
! }!
!}!
!!
END;
END;
}; .
PROCEDURE TypeName (t: Tree)
Class (..) :- {
IF (NoCodeClass * Properties) # {} THEN RETURN; END;
IF Trace IN Properties THEN
@"@ WI (Name); @",@
END;
}; .
PROCEDURE Forward /* Node, Class (sometimes) */ (t: Tree)
Class (..) :- {
IF (NoCodeClass * Properties) # {} THEN RETURN; END;
IF Referenced IN Properties THEN
FOR Visit := 1 TO Visits DO
!static void yyVisit! WN (Visit); WI (Name); ! ARGS((register ! WI (itTree); ! yyt!
Node := t;
Class := t;
ForallAttributes (t, Forward);
!));!
END;
END;
}; .
Attribute (..) :- {
IF (Parameter IN Properties) AND (Visit IN Usage) THEN
!, ! WI (Type); ! ! GenAttribute (AttrIndex, FALSE);
END;
}; .
PROCEDURE GenEvaluator /* Node, Class (sometimes), Visit */ (t: Tree)
Class (..) :- {
IF (NoCodeClass * Properties) # {} THEN RETURN; END;
IF Generated = InstCount THEN RETURN; END;
!case k! WI (Name); !: {!
Start := Generated + 1;
LOOP
IF Generated = InstCount THEN EXIT; END;
INC (Generated);
WITH Instance^ [Instance^ [Generated].Order] DO
IF (Left IN Properties) AND (Attribute^.Child.Partition > Visit) THEN
DEC (Generated); EXIT;
END;
END;
END;
Stop := Generated;
Class := t;
ForallAttributes (t, GenTempos);
FOR Start := Start TO Stop DO
i := Instance^ [Start].Order;
WITH Instance^ [i] DO
IF ({Inherited, Right, First} <= Properties) AND ({Dummy, Virtual, Demand} * Properties = {}) THEN
GenDemandEval (t);
IF IsElement (ORD ('X'), Options) AND (Trace IN t^.Class.Properties) THEN
@yyWriteEval (yyt, "@ WI (Selector^.Child.Name); !:! WI (Attribute^.Child.Name); @");@
IF Action # ADR (Action) THEN GenEvaluator (Action); END; !!
IF (Attribute^.Kind = Tree.Child) OR (Attribute^.Attribute.Type = itTree) THEN
!write! WI (itTree); ! (! GenAttribute (i, TRUE); !)!
ELSE
!write! WI (Attribute^.Child.Type); ! (! GenAttribute (i, TRUE); !) yyWriteNl ();!
END;
ELSIF IsElement (ORD ('Y'), Options) AND (Trace IN t^.Class.Properties) THEN
@yyWriteEval (yyt, "@ WI (Selector^.Child.Name); !:! WI (Attribute^.Child.Name); @");@
IF Action # ADR (Action) THEN GenEvaluator (Action); END;
ELSE
IF Action # ADR (Action) THEN GenEvaluator (Action); END;
END;
END;
IF ({Synthesized, Left, First} <= Properties) AND ({Dummy, Virtual, Demand} * Properties = {}) THEN
GenDemandEval (t);
IF IsElement (ORD ('X'), Options) AND (Trace IN t^.Class.Properties) THEN
@yyWriteEval (yyt, "@ WI (Attribute^.Child.Name); @");@
IF Action # ADR (Action) THEN GenEvaluator (Action); END; !!
IF Test IN Properties THEN
!writebool (yyb) yyWriteNl ();!
ELSIF (Attribute^.Kind = Tree.Child) OR (Attribute^.Attribute.Type = itTree) THEN
!write! WI (itTree); ! (! GenAttribute (i, TRUE); !)!
ELSE
!write! WI (Attribute^.Child.Type); ! (! GenAttribute (i, TRUE); !) yyWriteNl ();!
END;
ELSIF IsElement (ORD ('Y'), Options) AND (Trace IN t^.Class.Properties) THEN
@yyWriteEval (yyt, "@ WI (Attribute^.Child.Name); @");@
IF Action # ADR (Action) THEN GenEvaluator (Action); END;
ELSE
IF Action # ADR (Action) THEN GenEvaluator (Action); END;
END;
END;
IF ({Synthesized, Right, First} <= Properties) AND
(Attribute^.Child.Partition <= Selector^.Child.Class^.Class.Visits) THEN
IF IsElement (ORD ('Z'), Options) AND (Trace IN t^.Class.Properties) THEN
@yyWriteVisit (yyt, "@ WI (Selector^.Child.Name); ! !
WN (Attribute^.Child.Partition); @");@
END;
ChildVisit := Attribute^.Child.Partition;
Child := Selector;
!yyVisit! WN (ChildVisit); WI (Child^.Child.Type);
! (yyt->! WI (Name); !.! WI (Child^.Child.Name);
ForallAttributes (Child^.Child.Class, GenActualsRight);
!);!
END;
END;
END;
IF IsElement (ORD ('Z'), Options) AND (Trace IN t^.Class.Properties) THEN
!yyVisitParent (yyt);!
END;
!} break;!
}; .
Assign (..) :- {
WriteLine (Pos);
GenEvaluator (Results); !=! GenEvaluator (Arguments); !;!
}; .
Copy (..) :- {
j := Class^.Class.Instance^[i].CopyArg;
IF (Parameter IN Class^.Class.Instance^[i].Attribute^.Attribute.Properties) AND
(Parameter IN Class^.Class.Instance^[j].Attribute^.Attribute.Properties) THEN
IF (Left IN Class^.Class.Instance^[i].Properties) AND
(Left IN Class^.Class.Instance^[j].Properties) THEN
WriteLine (Pos);
GenAttribute (i, FALSE); ! =! GenEvaluator (Arguments); !;!
END;
ELSE
WriteLine (Pos);
GenEvaluator (Results); !=! GenEvaluator (Arguments); !;!
END;
}; .
TargetCode (..) :- {
WriteLine (Pos);
GenEvaluator (Code); !!
}; .
Check (..) :- {
WriteLine (Pos);
IF Condition # NoTree THEN
@if (! (@
IF IsElement (ORD ('X'), Options) THEN
!yyb = !
END;
GenEvaluator (Condition); !)) {! GenEvaluator (Statement); !; }!
IF Actions^.Kind = Tree.Check THEN
!else ! GenEvaluator (Actions);
END;
ELSE
IF IsElement (ORD ('X'), Options) THEN
!yyb = false; !
END;
GenEvaluator (Statement); !;!
GenEvaluator (Actions);
END;
}; .
Designator (..) :- {
Child2 := IdentifyAttribute (Class, Selector);
IF Child2 # NoTree THEN
ChildsClass := Child2^.Child.Class;
Attr := IdentifyAttribute (ChildsClass, Attribute);
IF Attr # NoTree THEN
GenAttribute (Class^.Class.AttrCount + Child2^.Child.InstOffset + Attr^.Attribute.AttrIndex, TRUE);
ELSE
WI (Selector); !:! WI (Attribute);
END;
ELSE
WI (Selector); !:! WI (Attribute);
END;
GenEvaluator (Next);
}; .
Ident (..) :- {
Attr := IdentifyAttribute (Class, Attribute);
IF Attr # NoTree THEN
GenAttribute (Attr^.Attribute.AttrIndex, TRUE);
ELSE
WI (Attribute);
END;
GenEvaluator (Next);
}; .
Any (..) :- {
WriteString (f, Code);
GenEvaluator (Next);
}; .
Anys (..) :- {
GenEvaluator (Layouts);
GenEvaluator (Next);
}; .
LayoutAny (..) :- {
WriteString (f, Code);
GenEvaluator (Next);
}; .
PROCEDURE Generated0 (t: Tree)
Class (..) :- {
Generated := 0;
}; .
PROCEDURE GenFormals1 /* Node, Class, Visit */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) AND (Visit IN Usage) THEN
!, yy! WI (Name);
END;
}; .
PROCEDURE GenFormals2 /* Node, Class, Visit */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) AND (Visit IN Usage) THEN
! ! WI (Type); ! ! GenAttribute (AttrIndex, FALSE); !;!
END;
}; .
PROCEDURE GenFormals3 /* Node, Class, Visit */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) AND (Visit IN Usage) THEN
! ,! WI (Type); ! ! GenAttribute (AttrIndex, FALSE);
END;
}; .
PROCEDURE GenActualsRight /* Node = current type, Class = subtype, Child, ChildVisit */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) AND (ChildVisit IN Usage) THEN
!, & ! GenAttribute (Class^.Class.AttrCount + Child^.Child.InstOffset + AttrIndex, TRUE);
END;
}; .
PROCEDURE GenActualsLeft /* Node = current type, Class = subtype, Visit */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) AND (Visit IN Usage) THEN
!, ! GenAttribute (AttrIndex, FALSE);
END;
}; .
PROCEDURE GenTempos /* Node, Class (sometimes), Visit, k */ (t: Tree)
Child (..) :- {
Child := t;
ForallAttributes (Class, GenTemposChildren);
}; .
Attribute (..) :- {
IF (Parameter IN Properties) AND (IdentifyAttribute (Node, Name) = NoTree) AND (Visit IN Usage) OR
(Demand IN Properties) AND NOT (Funct IN Properties) AND (AttrIndex # k) THEN
WI (Type); ! yy! WI (Name); !;!
END;
}; .
PROCEDURE GenTemposChildren /* Node, Class, Child */ (t: Tree)
Attribute (..) :- {
IF (Parameter IN Properties) OR
(Demand IN Properties) AND NOT (Funct IN Properties) THEN
j := Class^.Class.AttrCount + Child^.Child.InstOffset + AttrIndex;
IF (Demand IN Properties) OR
(({CopyDef, CopyUse} * Class^.Class.Instance^[j].Properties) = {}) OR
(j = Representative (j)) THEN
IF CheckUsage (Usage) THEN
WI (Type); ! ! WI (Child^.Child.Name); !yy! WI (Name); !;!
END;
END;
END;
}; .
PROCEDURE GenTemposLocal /* Node, Class */ (t: Tree)
Attribute (..) :- {
IF Parameter IN Properties THEN
! ! WI (Type); ! ! GenAttribute (AttrIndex, FALSE); !;!
END;
}; .
PROCEDURE GenDemandProc /* Node, Class */ (t: Tree)
Class (..) :- {
IF (NoCodeClass * Properties) # {} THEN RETURN; END;
Node := t;
ForallAttributes (Attributes, GenDemandProc);
}; .
Attribute (..) :- {
IF Demand IN Properties THEN
Class := Node;
k := AttrIndex;
IF Funct IN Properties THEN
!static ! WI (Type); ! y! WI (Class^.Class.Name); !y! WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
! (register ! WI (itTree); ! yyt)!
!# else!
! (yyt) register ! WI (itTree); ! yyt;!
!# endif!
ELSE
!static void y! WI (Class^.Class.Name); !y! WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
! (register ! WI (itTree); ! yyt, ! WI (Type); ! * ! GenAttribute (AttrIndex, FALSE); !)!
!# else!
! (yyt, ! GenAttribute (AttrIndex, FALSE); !)!
! register ! WI (itTree); ! yyt;!
! ! WI (Type); ! * ! GenAttribute (AttrIndex, FALSE); !;!
!# endif!
END;
!{!
! switch (yyt->Kind) {!
IF cOAG IN GrammarClass THEN
i := AttrIndex;
Class := Node;
Visit := Partition;
GenDemandProc2 (Class);
ForallClasses (Class^.Class.Extensions, GenDemandProc2);
Class := Node;
END;
! default: ;!
! }!
!}!
!!
k := 0;
END;
}; .
PROCEDURE GenDemandProc2 /* Node, Class, i, Visit */ (t: Tree)
Class (..) :- {
!case k! WI (Name); !: {!
WITH Instance^ [i] DO
Class := t;
ForallAttributes (t, GenTempos);
GenDemandEval (t);
IF Funct IN Properties THEN
GenDemandProc2 (Action);
ELSE
GenEvaluator (Action); !!
END;
END;
!} break;!
}; .
Assign (..) :- {
!return ! GenEvaluator (Arguments); !;!
}; .
Copy (..) :- {
!return ! GenEvaluator (Arguments); !;!
}; .
TargetCode (..) :- {
!NoBlockStatementForDemandFunctionAttributes;!
}; .
PROCEDURE GenDemandEval /* Node, Class, i */ (t: Tree)
Class (..) :- {
FOR j := 1 TO InstCount DO
WITH Instance^ [j] DO
IF IsRelated (i, j, DP) AND
(Demand IN Properties) AND NOT (Funct IN Properties) THEN
IF Left IN Properties THEN
AttrClass := GetClass (t, Attribute^.Child.Name);
! y! WI (AttrClass^.Class.Name); !y! WI (Attribute^.Child.Name);
! (yyt, ! GenAttribute (j, FALSE); !);!
ELSE
AttrClass := GetClass (Selector^.Child.Class, Attribute^.Child.Name);
! y! WI (AttrClass^.Class.Name); !y! WI (Attribute^.Child.Name);
! (yyt->! WI (Name); !.! WI (Selector^.Child.Name);
!, ! GenAttribute (j, FALSE); !);!
END;
END;
END;
END;
}; .